package cn.mw.cmdb.virtualization.strategy.handler.sync;

import cn.mw.cmdb.virtualization.dto.VirtualizationStorageDto;
import cn.mw.cmdb.virtualization.dto.unicloud.UniCloudStorageDto;
import cn.mw.cmdb.virtualization.param.VirtualizationParam;
import cn.mw.cmdb.virtualization.strategy.handler.SyncEngineDataHandler;
import cn.mw.microMonitorCommon.api.cmdb.VirtualizationDubboService;
import cn.mw.microMonitorCommon.entity.cmdb.DataSourceInstanceVo;
import cn.mw.microMonitorCommon.entity.cmdb.VirtualizationSyncVo;
import cn.mw.microMonitorCommon.entity.common.MwSyncEngineDto;
import cn.mw.microMonitorCommon.enums.SyncEngineTypeEnum;
import cn.mw.microMonitorCommon.enums.UnicloudTypeEnum;
import cn.mw.microMonitorCommon.util.CASApiClient;
import cn.mw.microMonitorCommon.util.RSAUtils;
import cn.mw.microMonitorCommon.util.XMLToClassUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.HttpUrl;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

/**
 * @description vcenter数据处理
 */
@Service
@Slf4j
public class SyncEngineUniCloudDataHandler extends SyncEngineDataHandler {

    private final String STORAGE_API = "/cas/casrs/storage/host/pool";

    private final String REQUEST_METHOD = "GET";

    @DubboReference(check = false,timeout = 10000000)
    private VirtualizationDubboService virtualizationDubboService;

    @Override
    public SyncEngineTypeEnum handlerType() {
        return SyncEngineTypeEnum.UniCloud;
    }

    @Override
    public List<VirtualizationStorageDto> getVirtualizationSyncStorageInfo(VirtualizationParam param, MwSyncEngineDto engineDto) {
        List<VirtualizationStorageDto> storageDtos = new ArrayList<>();
        try {
            String vmType = param.getVmType();
            String dataId = param.getDataId();
            CASApiClient client = new CASApiClient();
            String url = engineDto.getProtocolType()+"://"+engineDto.getIp()+STORAGE_API;
            if(StringUtils.isNotEmpty(vmType) && StringUtils.isNotEmpty(dataId)){
                UnicloudTypeEnum enumByType = UnicloudTypeEnum.getUnicloudTypeEnumByType(vmType);
                url = createCondition(url, enumByType, dataId);
            }
            String password = RSAUtils.decryptData(engineDto.getUserAuth(), RSAUtils.RSA_PRIVATE_KEY);
            String result = client.callApi(url, engineDto.getAccount(), password, REQUEST_METHOD, STORAGE_API, null);
            UniCloudStorageDto uniCloudStorageDto = XMLToClassUtil.convertXmlToEntity(result, UniCloudStorageDto.class);
            if(uniCloudStorageDto == null || CollectionUtils.isEmpty(uniCloudStorageDto.getStorages())){
                return storageDtos;
            }
            List<UniCloudStorageDto.Storage> storages = uniCloudStorageDto.getStorages();
            for (UniCloudStorageDto.Storage storage : storages) {
                VirtualizationStorageDto storageDto = new VirtualizationStorageDto();
                storageDto.setStorageName(storage.getName());
                storageDto.setTotalCapacity(storage.getTotalSizeFormat());
                storageDto.setAvailableCapacity(storage.getFreeSizeFormat());
                BigDecimal use = new BigDecimal(storage.getTotalSize()).subtract(new BigDecimal(storage.getFreeSize()));
                BigDecimal decimal = use.divide(new BigDecimal(storage.getTotalSize()),2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
                storageDto.setStorageUsageRate(decimal.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue()+"%");
                storageDtos.add(storageDto);
            }
            return storageDtos;
        }catch (Throwable e){
            log.error("getVirtualizationSyncStorageInfo() error",e);
        }
        return storageDtos;
    }

    @Override
    public void syncVirtualizationData(MwSyncEngineDto engineDto, VirtualizationParam param) {
        try {
            UnicloudTypeEnum[] unicloudTypeEnums = UnicloudTypeEnum.values();
            List<VirtualizationSyncVo> syncVoList = new ArrayList<>();
            //数据组装
            for (UnicloudTypeEnum unicloudTypeEnum : unicloudTypeEnums) {
                if(StringUtils.isEmpty(unicloudTypeEnum.getApi())){continue;}
                VirtualizationSyncVo syncVo = new VirtualizationSyncVo();
                syncVo.setEngineId(engineDto.getId());
                syncVo.setEngineDto(engineDto);
                syncVo.setUnicloudTypeEnum(unicloudTypeEnum);
                syncVoList.add(syncVo);
            }
            List<DataSourceInstanceVo> instanceVos = virtualizationDubboService.syncUnicloud(syncVoList);
            handlerInstanceData(instanceVos,param.getEngineId(),param);
            log.info("紫光云数据同步成功");
        }catch (Throwable e){
            log.error("紫光云数据同步失败",e);
        }
    }

    private String createCondition(String url,UnicloudTypeEnum enumByType,String dataId){
        HttpUrl.Builder builder = HttpUrl.parse(url).newBuilder();
        switch (enumByType){
            case HOST_POOL:
                builder.addQueryParameter("hpId",dataId.split("_")[1]);
                break;
            case CLUSTER:
                builder.addQueryParameter("clusterId",dataId.split("_")[1]);
                break;
            case HOST:
                builder.addQueryParameter("hostId",dataId.split("_")[1]);
                break;
        }
        return builder.build().toString();
    }
}
